<template>
  <div >
    <div class="title" >
      <div style="flex: 1;">
        扫描装车（扫描销售单）
      </div>
    </div>
    <div  class="order">
      <tiny-grid :data="state.orders" :height="gridHeight" border  >
        <tiny-grid-column type="index" width="60"></tiny-grid-column>
        <tiny-grid-column field="billNo" title="单据号" width="170"  headerAlign="center"></tiny-grid-column>
        <tiny-grid-column field="billDate" title="票据日期" width="120"  headerAlign="center" align="center"> </tiny-grid-column>
        <tiny-grid-column field="buName" title="终端名称"  headerAlign="center"></tiny-grid-column>
        <tiny-grid-column field="address" title="地址"  headerAlign="center"></tiny-grid-column>
        <tiny-grid-column   title="操作" width="100" fixed="right" align="center">
          <template #default="data">
            <tiny-button size="mini" @click="delRow(data.row)" type="info">删除</tiny-button>
          </template>
        </tiny-grid-column>
      </tiny-grid>
    </div>
    <!--    下面汇总及车辆信息选择-->
    <div style=" display: flex;flex-direction: row;">
      <div style="flex: 1;padding-top: 2px;" ref="wrapRef">
        <tiny-grid :data="state.grpData"  height="400px" border size="mini" show-footer :footer-method="footerMethod">
          <tiny-grid-column type="index" width="60"></tiny-grid-column>
          <tiny-grid-column field="invName" title="装车商品名称" headerAlign="center"></tiny-grid-column>
          <tiny-grid-column field="spec" title="规格" width="100"  headerAlign="center" align="center"></tiny-grid-column>
          <tiny-grid-column field="unit" title="单位" width="80" align="center"  headerAlign="center"></tiny-grid-column>
          <tiny-grid-column field="qty" title="数量" width="100" align="right"  headerAlign="center"></tiny-grid-column>
          <tiny-grid-column field="assQty" title="辅助数量" width="120" align="right"  headerAlign="center"></tiny-grid-column>
        </tiny-grid>
      </div>
      <div style="padding: 10px 30px;height: 400px;background: white;" >
        <div style="padding: 10px 0;color: lightseagreen;">
         送货员
        </div>
        <div>
          <JDeliver v-model="state.deliverNames"></JDeliver>
        </div>
        <div style="text-align: center;margin-top: 50px;">
          <div>
            <JButton size="large" type="info" @click="doCargo" style="width: 120px;"> 装车</JButton >
          </div>
          <div style="text-align: center;margin-top: 70px;">
            <JButton  size="large" @click="clearCargo" style="width: 120px;"> 清空</JButton >
          </div>
        </div>
      </div>
<!--      <div style="height: 300px;overflow: auto;">-->
<!--        {{test}}-->
<!--      </div>-->
    </div>
    <tiny-dialog-box v-model:visible="state.showcargo" title="装车提示">
      <div>确定装车？</div>
      <div style="margin-top: 50px;text-align: center;margin-bottom: 30px;">
        <JButton style="height: 50px;width: 150px;" @click="state.showcargo=false">取消</JButton>
        <JButton style="margin-left: 120px;height: 50px;width: 150px;" type="info" @click="confirmCargo">确定</JButton>
      </div>
    </tiny-dialog-box>
    <tiny-dialog-box v-model:visible="state.showRet" title="扫描结果" fullscreen>
      <div class="ocr">
        <div v-for="(item, index) in state.ocrJson" :key="index" style="margin-bottom: 10px;">
          <template v-if="item.type === 'plain' ">
            <div v-for="(line, ind) in item.lines" :key="ind">
              <span v-if="line.score > 0.9">{{line.text}}</span>
            </div>
          </template>
          <template v-if="item.type === 'table_with_line'">
            <table>
              <thead>
              <tr>
                <template v-for="(th, thInd) in item.table_cells" :key="thInd">
                  <th v-if="th.start_row===0" style="width: 150px;">{{th.text}}</th>
                </template>
              </tr>
              </thead>
              <tbody>
              <template  v-for="thInd in (Number(item.table_rows) - 1)" :key="thInd">
                <tr >
                  <template v-for="(th, tdind) in item.table_cells" :key="tdind">
                    <td
                        v-if="th.start_row===thInd"
                        :colspan="item.table_cells[tdind].end_col - item.table_cells[tdind].start_col + 1"
                    >{{th.text}}</td>
                  </template>
                </tr>
              </template>
              </tbody>
            </table>
          </template>
        </div>
      </div>
    </tiny-dialog-box>
    <doprint ref="doPrintss" show-title :show-print-both="false" :show-print-bill="false" :show-print-add="true" @addNew="addNew" @hide="addNew"></doprint>
  </div>
</template>
<script setup>
// 订单分配
import Doprint from "@/views/ps/doprint.vue";
import tool from "@/utils/tool";
import JDeliver from "@/views/ps/JDeliver.vue";
import {computed, onBeforeMount, onMounted, ref} from "vue";
const gridHeight = ref(300)
const state = ref({
  orders: [],
  grpData: [],
  deliverModal: false,
  showModal: false,
  showcargo: false,
  title: '',
  today: tool.getDay(),
  testVal: '',
  drivers: [],
  deliverNames: '',
  user: {},
  showRet: false,
  sets: {},
  ocrJson: []
})
const uuid = ref('')
const doPrintss = ref(null)
const goodList = ref([])
const tbWidth = ref(800)
const wrapRef = ref(null)
const test = ref([])
onBeforeMount(() => {
  state.value.user = tool.data.getUser()
  tool.post('app/py', {"which": "pssets"}).then(ret => {
    if (ret.stat) {
      state.value.sets = ret.data
    }
  })
  tool.post('justdeliver/getGoodList' ).then(ret => {
    if (ret.stat) {
      goodList.value = ret.data
    }
  })
})
onMounted(() => {
  window.ocr = doOcr
  window.ocrret = seeJson
  gridHeight.value = window.innerHeight - 400 - 42
  if(wrapRef.value) {
    let rec = wrapRef.value.getBoundingClientRect()
    tbWidth.value = rec.width
  }
  tool.sendToPy({name: 'openCam'})
})
const seeJson = (params) => {
  state.value.showRet = true
  if(params) {
    state.value.ocrJson = params
  }
}
const footerMethod = ({ columns, data }) => {
  if (data.length === 0) {
    return [
      ['合计', '', '', '',0]
    ]
  }
  return [
    columns.map((column, columnIndex) => {
      if (columnIndex === 0) {
        return '合计'
      }
      if (column.property === 'qty') {
        return data.map((item) => item[column.property]).reduce((acc, item) => acc + item)
      }
      return null
    })
  ]
}
const playAudio = (str) => {
  // tool.sendToPy({name: 'play', sound: str})
  // 创建AudioContext
  const audioContext = new (window.AudioContext || window.webkitAudioContext)();
  // 加载音频文件
  fetch('/audio/' + str + '.wav')
      .then(response => response.arrayBuffer())
      .then(arrayBuffer => audioContext.decodeAudioData(arrayBuffer))
      .then(audioBuffer => {
        // 创建音频源节点
        const source = audioContext.createBufferSource();
        source.buffer = audioBuffer;
        // 连接到输出
        source.connect(audioContext.destination);
        // 播放
        source.start();
      })
      .catch(e => console.error('Error with decoding audio data', e));
}
const ocrsuc = (str) => {
  // playAudio(str)
}

const doOcr = (params) => {
  let tables = params
  try {
    let bill = {
      headInfo: [],
      infos: []
    }
    for (let i = 0; i < tables.length; i++) {
      let item = tables[i]
      if (item.type === "plain") {
        if (item.lines.length > 0) {
          for (let j = 0; j < item.lines.length; j++) {
            let line = item.lines[j]
            if (line.score > 0.91) {
              let txt = tool.xe.trim(line.text)
              bill.headInfo.push(txt)
            }
          }
        }
      }
      if (item.type === "table_with_line") {
        let infos = []
        let rows = item['table_rows']
        let cols = item['table_cols']
        if (rows > 0 && cols > 0 && item['table_cells']) {
          let info = {}
          let tb_header = []
          for (let j = 0; j < item['table_cells'].length; j++) {
            let cell = item['table_cells'][j]
            let start_row = cell['start_row']
            let start_col = cell['start_col']
            let end_col = cell['end_col']
            if (start_row === 0) {
              if (cell.text)
                tb_header.push({col: {start: start_col, end: end_col}, txt: tool.xe.trim(cell.text)})
            } else {
              break
            }
          }
          for (let j = 0; j < item['table_cells'].length; j++) {
            let cell = item['table_cells'][j]
            let start_row = cell['start_row']
            let start_col = cell['start_col']
            let end_col = cell['end_col']
            if (start_row > 0) {
              if(start_row !== item['table_cells'][j-1].start_row && start_col === 0) {
                if(!tool.xe.isEmpty(info)) infos.push(tool.xe.clone(info, true))
              }
              if(cell.text.indexOf('合计') !== -1 || cell.text.indexOf('总计') !== -1 ) break
              for (let k = 0; k < tb_header.length; k++) {
                if(start_col===tb_header[k].col.start && end_col ===tb_header[k].col.end) {
                  info[tb_header[k].txt] = tool.xe.trim(cell.text)
                }
              }
            }
          }
        }
        bill.infos = infos
        break
      }
    }
    if(bill.infos.length === 0) {
      return tool.err('没有商品信息')
    }
    if(!uuid.value) uuid.value = tool.uuid()
    tool.post('justdeliver/gpList', {formData: bill, uuid:uuid.value }).then(ret => {
      if(ret.stat) {
        state.value.orders = ret.data.orders
        state.value.grpData = ret.data.grpData
        playAudio('suc')
      }
      else {
        if(ret.msg.indexOf('已配送') !== -1) {
          playAudio('yps')
        }
        else if(ret.msg.indexOf('合计失败') !== -1) {
          playAudio('sbsb')
        }
        else {
          playAudio('err')
        }
        return tool.err(ret.msg)
      }
    })
  }
  catch (e) {
    return []
  }
}


const deepEqual = (obj1, obj2) => {
  if (obj1 === obj2) return true;

  if (isPrimitive(obj1) || isPrimitive(obj2)) return obj1 === obj2;

  if (Object.keys(obj1).length !== Object.keys(obj2).length) return false;

  for (let key in obj1) {
    if (!obj2.hasOwnProperty(key)) return false;
    if (!deepEqual(obj1[key], obj2[key])) return false;
  }
  return true;
}
const isPrimitive = (val) => {
  return val == null || typeof val !== 'object';
}
const delRow = (row) => {
  tool.post('justdeliver/delCargoItem', row,true).then(ret => {
    if(ret.stat) {
      state.value.orders = ret.data.orders
      state.value.grpData = ret.data.grpData
    }
  })
}
const reload = () => {
  state.value.orders = []
  state.value.grpData = []
  state.value.deliverNames = ''
}
const addNew = () => {
  reload()
}
const clearCargo = () => {
  tool.confirm('清除已选中的装车记录').then(() => {
    state.value.orders = []
    state.value.deliverNames = ''
  })
}
// 装车
const doCargo = () => {
  if (!state.value.deliverNames) return tool.err('请选择送货员')
  if (state.value.orders.length === 0) return tool.err('至少选择 1 条票据')
  state.value.showcargo = true
}
const confirmCargo = () => {
  let passdata = {
    deliverNames: state.value.deliverNames,
    uuid: uuid.value
  }
  tool.post('justdeliver/toCargo', passdata).then(ret => {
    if (ret.stat) {
      state.value.showcargo = false
      uuid.value = ''
      doPrintss.value.print(ret.data)
    }
  })
}

const removeDuplicatesRecursive = (arr, result = [], index = 0) => {
  // 如果数组遍历完毕，返回结果
  if (index >= arr.length) {
    return result;
  }
  let currentObj = arr[index];
  // 检查当前对象是否在结果中已经存在，考虑了嵌套的对象
  let isDuplicate = result.some(existingObj => deepEqual(existingObj, currentObj));
  // 如果当前对象不是重复的，则添加到结果中
  if (!isDuplicate) {
    result.push(currentObj);
  }
  // 递归调用，检查下一个对象
  return removeDuplicatesRecursive(arr, result, index + 1);
}
// defineExpose({doOcr,seeJson})
</script>

<style scoped lang="scss">


.title {
  text-align: center;
  font-weight: bold;
  font-size: 22px;
  background-color: #01aaee;
  color: white;
  height: 40px;
  line-height: 40px;
  display: flex;
}

.s-item {
  border-bottom: 1px solid #F2F2F2;
  padding: 5px 0;
  margin-bottom: 10px;
}


.undeliver tr:hover {
  background-color: #f8f8f9;
}

.pd2 {
  padding: 2px;
}

.grid td {
  padding-left: 2px;
}

.order {
  padding-top: 2px;
}

.br {
  border-right: 1px solid #dedede;
}

.order .grid td {
  /*background-color: white;*/
}

.bb {
  border-bottom: 1px solid #dedede;
}

.bt {
  border-top: 1px solid #dedede;
}

.bl {
  border-left: 1px solid #dedede;
}

.tc {
  text-align: center;
}

.tr {
  text-align: right;
}

.order td, .order th {
  height: 30px;
  line-height: 30px;
}

.order td {
  color: #2b85e4;
}

.order .grid tr {
  /*background-color: white;*/
}

.order .grid tr:hover {
  background-color: gainsboro;
}

.grid tr {
  /*background-color: white;*/
}

.order td i {

}

.order td i:hover {
  cursor: pointer;
  color: red;
}

.undeliver {
}

.undeliver th {
  padding: 5px 3px;
}

.undeliver td {
  padding: 5px 3px;
}

li {
  margin-top: 10px;
}
.ocr {
  td {
    border: 1px solid #01aaee;
  }
  th {
    border: 1px solid #01aaee;
  }
}

.orow:hover, .orow:active {
  background-color: #2db7f5;
  color: white;
}
</style>